Emberveil sourcegame/2006Scape Server/src/main/java/com/rs2/event/UniversalEventProvider.java
package com.rs2.event;
import com.google.common.base.Preconditions;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.rs2.game.players.Player;
import com.rs2.util.ClassUtils;
import java.util.Collection;
import java.util.Optional;
import java.util.function.Consumer;
/**
* A universal event provider which posts, provides and deprives subscribers.
*
* @author Ryley Kimmel <ryley.kimmel@live.com>
*/
public final class UniversalEventProvider implements EventProvider {
/**
* A {@link Multimap} of {@link Event} classes to subscribers.
*/
private final Multimap<Class<? extends Event>, EventSubscriber<? super Event>> events = ArrayListMultimap.create();
/**
* The universal context of this event provider.
*/
private final EventContext context = new UniversalEventContext();
@SuppressWarnings("unchecked")
@Override
public void provideSubscriber(EventSubscriber<?> subscriber) {
checkSubscriber(subscriber, annotation -> events.put(annotation.value(), (EventSubscriber<? super Event>) subscriber));
}
@SuppressWarnings("unchecked")
@Override
public void depriveSubscriber(EventSubscriber<?> subscriber) {
checkSubscriber(subscriber, annotation -> events.remove(annotation.value(), (EventSubscriber<? super Event>) subscriber));
}
private void checkSubscriber(EventSubscriber<?> subscriber, Consumer<SubscribesTo> consumer) {
Optional<SubscribesTo> optional = ClassUtils.getAnnotation(subscriber.getClass(), SubscribesTo.class);
Preconditions.checkArgument(optional.isPresent(), String.format("%s is not annotated with @SubscribesTo", subscriber.getClass()));
consumer.accept(optional.get());
}
@Override
public <E extends Event> void post(Player player, E event) {
Collection<EventSubscriber<? super Event>> subscribers = events.get(event.getClass());
for (EventSubscriber<? super Event> subscriber : subscribers) {
/* Check to be sure we can subscribe to the event. */
if (subscriber.test(event)) {
subscriber.subscribe(context, player, event);
/* If the chain is broken, don't continue parsing subscribers. */
if (context.isChainBroken()) {
break;
}
}
}
context.repairSubscriberChain();
}
public Multimap<Class<? extends Event>, EventSubscriber<? super Event>> getEvents() {
return events;
}
}